package com.kun.base.ui

import android.app.Activity
import android.app.Application
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.kun.base.BaseApplication

/**
 * baseFragment
 *  @author : Kun
 *  @date : 2021/4/13
 *  @time : 18:12
 */
open class BaseFragment :Fragment(){
    private var mFragmentProvider: ViewModelProvider? = null
    private var mActivityProvider: ViewModelProvider? = null
    private var mApplicationProvider: ViewModelProvider? = null

    /**
     * 获取fragment级 ViewModel
     * @param modelClass vm
     * @param <T> vm
     * @return vm
    </T> */
    protected fun <T : ViewModel?> getFragmentScopeViewModel(modelClass: Class<T>): T {
        if (mFragmentProvider == null) {
            mFragmentProvider = ViewModelProvider(this)
        }
        return mFragmentProvider!!.get(modelClass)
    }

    /**
     * 获取activity级 ViewModel
     * @param modelClass vm
     * @param <T> vm
     * @return vm
    </T> */
    protected fun <T : ViewModel?> getActivityScopeViewModel(modelClass: Class<T>): T {
        if (mActivityProvider == null) {
            mActivityProvider = activity?.let { ViewModelProvider(it) }
        }
        return mActivityProvider!!.get(modelClass)
    }

    /**
     * 获取application级 ViewModel
     * @param modelClass vm
     * @param <T> vm
     * @return vm
    </T> */
    protected fun <T : ViewModel?> getApplicationScopeViewModel(modelClass: Class<T>): T {
        if (mApplicationProvider == null) {
            mApplicationProvider = ViewModelProvider(activity!!.application as BaseApplication, getApplicationFactory(activity!!) )
        }
        return mApplicationProvider!!.get(modelClass)
    }

    private fun getApplicationFactory(activity: Activity): ViewModelProvider.Factory {
        checkActivity(this)
        val application = checkApplication(activity)
        return ViewModelProvider.AndroidViewModelFactory.getInstance(application)
    }

    private fun checkApplication(activity: Activity): Application {
        return activity.application
            ?: throw IllegalStateException(
                "Your activity/fragment is not yet attached to "
                        + "Application. You can't request ViewModel before onCreate call."
            )
    }

    private fun checkActivity(fragment: Fragment) {
        val activity = fragment.activity
            ?: throw IllegalStateException("Can't create ViewModelProvider for detached fragment")
    }
}